/**
 * 
 */
package org.jinion.database.model;

import java.sql.ResultSet;
import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jinion.database.model.impl.TableColumn;
import org.jinion.database.model.impl.TableRow;
import org.jinion.exception.JinionException;
import org.jinion.exception.JinionRuntimeException;
import org.jinion.util.DataList;

/**
 * This is the wapper of ResultSet.
 * @author zhlmmc
 *
 */
public abstract class AbstractTable {
	private static final Log log = LogFactory.getLog(AbstractTable.class);
	
	protected DataList<TableColumn> columns;
	protected DataList<TableRow> rows;
	protected ResultSet resultSet;
	
	public AbstractTable(ResultSet resultSet) throws JinionException{
		this.resultSet = resultSet;
		columns = new DataList<TableColumn>();
		rows = new DataList<TableRow>();
		
		this.buildTable();
	}
	
	
	/**
	 * Traversal the ResultSet to fill the table.
	 * This method will be called in the constructor of AbstractTable.
	 * @throws JinionException
	 */
	protected abstract void buildTable() throws JinionException;
	
	
	public int getColumnIndex(String columnName){
		for (Iterator<TableColumn> iterator = this.columns.iterator(); iterator.hasNext();) {
			TableColumn column = iterator.next();
			if (column.getColumnName().equals(columnName)) {
				return column.getIndex();
			}
		}
		return -1;
	}
	
	/**
	 * Index starts from 1, 2...
	 * @param columnIndex
	 * @return
	 */
	public TableColumn getColumn(int columnIndex){
		if (columnIndex < 1 || columnIndex > this.columns.size()) {
			JinionRuntimeException jre = new JinionRuntimeException("ColumnIndex ? is out of bound.", columnIndex);
			log.error(jre);
			throw jre;
		}
		else{
			return this.columns.get(columnIndex);
		}
	}
	
	public DataList<TableColumn> getColumns() {
		return columns;
	}

	/**
	 * Index starts from 1, 2...
	 * @param rowIndex
	 * @return
	 */
	public TableRow getRow(int rowIndex){
		if (rowIndex < 1 || rowIndex > rows.size()) {
			JinionRuntimeException jre = new JinionRuntimeException("RowIndex ? is out of bound.", rowIndex);
			log.error(jre);
			throw jre;
		}
		else{
			return this.rows.get(rowIndex);
		}
	}

	public DataList<TableRow> getRows() {
		return rows;
	}

	/**
	 * Get the ResultSet returned by database driver.<br>
	 * It is not recommended to operate the ResultSet directly. The database connection may be closed at anytime!
	 * @return ResultSet
	 */
	public ResultSet getResultSet(){
		return this.resultSet;
	}
}
